%%%-------------------------------------------------------------------
%%% File    : p47.erl
%%% Author  : Plamen Dragozov <plamen at dragozov.com>
%%% Description : 
%%% The first two consecutive numbers to have two distinct prime 
%%% factors are:
%%%
%%% 14 = 2 * 7
%%% 15 = 3 * 5
%%%
%%% The first three consecutive numbers to have three distinct prime 
%%% factors are:
%%%
%%% 644 = 2^2 * 7 * 23
%%% 645 = 3 * 5 * 43
%%% 646 = 2 * 17 * 19.
%%%
%%% Find the first four consecutive integers to have four distinct 
%%% primes factors. What is the first of these numbers?
%%%
%%%
%%% Created :  2 Jan 2009
%%%-------------------------------------------------------------------
-module(p47).

%% API
-compile(export_all).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: solution() -> N
%% Description:
%% Returns the first of the first 4 consecutive integers to have 4 distinct prime factors.
%%--------------------------------------------------------------------
solution() ->
    for(2, 2, 1, 17, [2, 3, 5, 7, 11, 13]).%starting at 17 

%Iterating through the numbers with a "window" of size 4 checking if the consecutive 4 numbers have 4 factors.
for(F1, F2, F3, Next, [H|T] = Primes) ->
    F = factor_count(Next, H, 0, T, 0), 
    case F =:= 4 andalso F1 =:= 4 andalso F2 =:= 4 andalso F3 =:= 4 of
        true ->
            Next - 3;
        _ ->
            NewPrimes = case F of 
                            0 -> Primes ++ [Next];
                            _ -> Primes
                        end,
            for(F2, F3, F, Next + 1, NewPrimes)
    end.

%%====================================================================
%% Internal functions
%%====================================================================
%Hom many prime factors does N has.
factor_count(N, I, Counter, _Primes,  Acc) when I > (N div 2)->
    case Counter > 0 of
        true when N > 0 -> Acc + 2;
        true -> Acc + 1;
        _ when N > 0 andalso Acc > 0 -> Acc + 1;
        _ -> Acc
    end;
factor_count(N, I, Counter, [H|T] = Primes, Acc) ->
    case true of
        true when (N rem I) =:= 0 ->
            
            factor_count(N div I, I, Counter + 1, Primes, Acc);
        true when Counter > 0 ->
            factor_count(N, H, 0, T, Acc + 1);
        _ ->
            factor_count(N, H, 0, T, Acc)
    end.
